home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Snippets / Stuart's Tech Notes / Stu’sThreadUtils / PipeLine.c < prev    next >
Encoding:
Text File  |  1994-03-19  |  2.3 KB  |  72 lines  |  [TEXT/KAHL]

  1. // Pipeline.c
  2. //
  3. // Copyright (C) 6th March 1994  Stuart Cheshire <cheshire@cs.stanford.edu>
  4. //
  5. // See PipeLine.h for usage instructions.
  6.  
  7. #include "PipeLine.h"
  8.  
  9. #define next(x) (((x)+1 < p->data_end) ? (x)+1 : p->data)
  10. #define isfull()    (next(p->inptr) == p->outptr)
  11. #define isempty()   (p->inptr == p->outptr)
  12.  
  13. // Normally chars counts the number of characters in the pipeline,
  14. // and spaces counts the number of spaces. However, when there are
  15. // NO ACTIVE WRITERS, chars is set to one greater than it should be.
  16. // When the PipeLineGetData tries to read this phantom character,
  17. // it recognises that there are no more writers, and returns -1 to
  18. // indicate this fact. This is why in PipeLineInit, chars is initialized
  19. // to one, because writers is initialized to zero.
  20.  
  21. void PipeLineInit(PipeLine *p, unsigned char *buffer, unsigned long size)
  22.     {
  23.     p->inptr = p->outptr = p->data = buffer;
  24.     p->data_end = buffer + size;
  25.     p->writers = 0;
  26.     SemaphoreInit(&p->mutex, 1);
  27.     SemaphoreInit(&p->chars, 1);
  28.     SemaphoreInit(&p->spaces, size-1);
  29.     }
  30.  
  31. void PipeLineOpen(PipeLine *p)
  32.     {
  33.     SemaphoreP(&p->mutex);
  34.     if (p->writers++ == 0) SemaphoreP(&p->chars);
  35.     SemaphoreV(&p->mutex);
  36.     }
  37.  
  38. void PipeLineClose(PipeLine *p)
  39.     {
  40.     SemaphoreP(&p->mutex);
  41.     if (--p->writers == 0) SemaphoreV(&p->chars);
  42.     SemaphoreV(&p->mutex);
  43.     }
  44.  
  45. void PipeLinePutData(PipeLine *p, unsigned char x)
  46.     {
  47.     SemaphoreP(&p->spaces);            // Wait until we have a space
  48.     SemaphoreP(&p->mutex);            // Grab the lock
  49.     *p->inptr = x;                    // Put the character in
  50.     p->inptr = next(p->inptr);        // Advance pointer to the next slot
  51.     SemaphoreV(&p->mutex);            // Release the lock
  52.     SemaphoreV(&p->chars);            // Indicate that we have another character
  53.     }
  54.  
  55. short PipeLineGetData(PipeLine *p)
  56.     {
  57.     int x;
  58.     SemaphoreP(&p->chars);            // Wait until we have a character
  59.     SemaphoreP(&p->mutex);            // Grab the lock
  60.     if (isempty())                    // If the buffer is empty,
  61.         {                            // then there are no active writers, so
  62.         SemaphoreV(&p->mutex);        // Release the lock
  63.         SemaphoreV(&p->chars);        // Put the 'fake' character back
  64.         return(NO_WRITERS);            // Return -1 to the reader
  65.         }
  66.     x = *p->outptr;                    // Get the character out
  67.     p->outptr = next(p->outptr);    // Advance pointer to the next slot
  68.     SemaphoreV(&p->mutex);            // Release the lock
  69.     SemaphoreV(&p->spaces);            // Indicate that we have another space
  70.     return(x);
  71.     }
  72.